﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Threading;
using UnityEngine;

/// <summary>
/// 客户端
/// </summary>
public class TCPClient
{
    private string ip = "172.16.2.159";
    private int port = 7788;
    private TcpClient tcpClient;

    private NetworkStream stream;
    private byte[] cacheData = new byte[1024]; // 数据缓存池

    private List<byte> cacheBytes = new List<byte>();
    public void StartClient(string ipStr)
    {
        try
        {
            ip = ipStr;
            tcpClient = new TcpClient(ip, port);//连接服务器
            stream = tcpClient.GetStream();
            curPackage = new BufferInfo();
            //开始监听数据读取

            stream.BeginRead(cacheData, 0, cacheData.Length, AsyncReciveCallback, stream);
        }
        catch (Exception e)
        {
            Debug.LogError(e.ToString());
        }
    }

    private BufferInfo curPackage = null;
    private void AsyncReciveCallback(IAsyncResult result)
    {
        var netSt = result.AsyncState as NetworkStream;
        int count = netSt.EndRead(result);
        //处理网络包数据
        if(count>0)
        {
            byte[] curReciveBytes = new byte[count];
            //拷贝当前数据包的内容
            Buffer.BlockCopy(cacheData, 0, curReciveBytes, 0, count);
            cacheBytes.AddRange(curReciveBytes);

            bool recived = curPackage.CheckRecived(cacheBytes);
            if(recived)//收完了 
            {
               var package = curPackage.WrapCacheBytes(cacheBytes); //处理数据并且清除已经读取的数据

                //处理网络包逻辑
                ProcessPackage(package);
            }
            //没收完
        }
        stream.BeginRead(cacheData, 0, cacheData.Length, AsyncReciveCallback, netSt);
    }

    private void ProcessPackage(Package package)
    {
        InjectFixManager.Ins.LoadPatchBytes(package.type, package.data);
    }

    public void CloseTCPClient()
    {
        if(stream!=null)
           stream.Close();
        if(tcpClient != null)
            tcpClient.Close();

        stream = null;
        tcpClient = null;
    }
}
public class bytestools
{
    public static int byte2int(byte[] bytes)
    {
        int value = 0;
        value = (int)(bytes[0] |
                       bytes[1] << 8 |
                       bytes[2] << 16 |
                       bytes[3] << 24);
        return value;
    }
    public static byte[] int2byte(int value)
    {
        byte[] bytes = new byte[4];
        bytes[0] = (byte)value;
        bytes[1] = (byte)(value >> 8);
        bytes[2] = (byte)(value >> 16);
        bytes[3] = (byte)(value >> 24);
        return bytes;
    }
}
public class BufferInfo
{
    //固定16个头
    private int reciveNum = 0;//当前数据包已经接受的消息
    private int headerType = 0;
    private int headerLen = 0;
    private byte[] data;
    public BufferInfo()
    {}

    public bool CheckRecived(List<byte> bytes)
    {
        if (bytes.Count >= 8)
        {
            byte[] type =new byte[4] { bytes[0], bytes[1], bytes[2], bytes[3] };
            headerType = bytestools.byte2int(type);
            byte[] len = new byte[4] { bytes[4], bytes[5], bytes[6], bytes[7] };
            headerLen = bytestools.byte2int(len);

            if ((bytes.Count - 8) >= headerLen)//数据已经是一个包了
            {
                return true;
            }
            return false;
        }
        else
        {
            return false;
        }
    }

    public Package WrapCacheBytes(List<byte> bytes)
    {
        data = new byte[headerLen];
        var surArr = bytes.ToArray();
        Buffer.BlockCopy(surArr, 8, data, 0, headerLen);

        //处理逻辑
        bytes.RemoveRange(0, 8 + headerLen);

        var package = new Package(headerType, data);
        headerType = 0;
        headerLen = 0;
        data = null;

        return package;
    }
}

public class Package
{
    public int type;
    public byte[] data;

    public Package(int type, byte[] data)
    {
        this.type = type;
        this.data = data;
    }
}
